package com.nwpu.main;

import com.nwpu.pojo.Message;
import com.nwpu.pojo.User;

import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;
import java.util.*;

/**
 * MethodSetImpl
 *
 * @author 龙虹宇
 * @version 1.0
 * @date 2023/11/24
 */
public class MethodSetImpl extends UnicastRemoteObject implements MethodSet {
    // 静态用户集合
    private static Hashtable<Integer, User> userHashtable = new Hashtable<>();
    private static Collection<User> users;
    // 静态信息集合
    private static Hashtable<Integer, Message> messageHashtable = new Hashtable<>();
    private static Collection<Message> messages;

    // 指令集
    private static final String[] INSTRUCTIONS = {
            "register", "showUsers"
            , "checkMessages", "leaveMessage"
            , "help", "quit"
    };
    // 指令集描述
    private static final String[] INSTRUCTIONS_DES = {
            "注册用户", "查看用户列表"
            , "查询用户留言", "给其他用户留言"
            , "查看帮助", "退出"
    };
    // 指令集参数
    private static final String[] INSTRUCTIONS_ARGS = {
            "[username] [password]"
            , "no args"
            , "[username] [password]"
            , "[username] [password] [receiver_name] [message_text]"
            , "no args", "no args"
    };

    protected MethodSetImpl() throws RemoteException {
    }

    /**
     * 获取用户集合
     * 
     * @return
     */
    private static synchronized Collection<User> getUsers() {
        return userHashtable.values();
    }

    /**
     * 获取信息集合
     * 
     * @return
     */
    private static synchronized Collection<Message> getMessages() {
        return messageHashtable.values();
    }
    
    /**
     * 注册
     *
     * @param username
     * @param password
     * @return  s：注册成功
     *          f：注册失败
     * @throws RemoteException
     */
    @Override
    public String register(String username, String password) throws RemoteException {
        // 如果用户名不存在
        if (!hasUsername(username)) {
            // 创建新用户
            User user = new User(username, password);
            // 添加用户到集合
            userHashtable.put(user.getId(), user);

            System.out.println(showUsers());
            return "s";
        }
        return "f";
    }

    /**
     * 添加信息
     *
     * @param username
     * @param password
     * @param receiverName
     * @param messageText
     * @return  success：    添加信息成功
     *          less：       当前注册用户不足两人
     *          same_name：  创建者和参会者相同
     *          wrong：      用户名或密码或参会者用户名错误
     * @throws RemoteException
     */
    @Override
    public String leaveMessage(String username, String password, String receiverName, String messageText) throws RemoteException {
        // 1. 判断：用户名和密码是否正确
        // 1.1 判断当前是否存在两个及以上的user
        if (userHashtable.size() < 2) return "less";
        // 1.2 获取users集合
        users = getUsers();
        // 判断1标记
        boolean flag1 = false;
        // 2. 判断：参会者用户名是否正确
        // 2.1 判断参会者用户名和创建者用户名是否是同一个人
        if (username.equals(receiverName)) return "same_name";
        // 判断2标记
        boolean flag2 = false;
        // 2.2 遍历users并判断条件
        for (User user : users) {
            if (user.getUsername().equals(username)
                    && user.getPassword().equals(password)) {
                flag1 = true;
                continue;
            }
            if (user.getUsername().equals(receiverName)) {
                flag2 = true;
            }
            if (flag1 && flag2) break;
        }
        if (!(flag1 && flag2)) return "wrong";
        // 3. 创建信息
        Message message = new Message(username, receiverName, new Date().toString(), messageText);
        messageHashtable.put(message.getId(), message);

        System.out.println(displayMessages());
        return "success";
    }

    /**
     * 查询信息
     *
     * @param username
     * @param password
     * @return  no_user：    未有注册用户
     *          wrong：      用户名或密码错误
     *          no_message： 未有添加信息
     *          ==Messages== + xx：  查询成功
     *          none：       未查询到结果
     * @throws RemoteException
     */
    @Override
    public String checkMessages(String username, String password) throws RemoteException {
        // 1. 判断：用户名和密码是否正确
        // 1.1 判断是否存在用户
        if (userHashtable.isEmpty()) return "no_user";
        users = getUsers();
        // 判断1标志
        boolean flag1 = false;
        for (User user : users) {
            if (user.getUsername().equals(username)
                    && user.getPassword().equals(password)) {
                flag1 = true;
                break;
            }
        }
        if (!flag1) return "wrong";
        // 2. 判断：信息列表是否为空
        if (messageHashtable.isEmpty()) return "no_message";

        Vector<Message> messageVector = new Vector<>();
        messages = getMessages();
        // 3. 查询信息
        for (Message message : messages) {
            if (username.equals(message.getReceiverName())) {
                messageVector.add(message);
            }
        }
        // 4. 如果查询到了信息，则添加到返回中
        if (!messageVector.isEmpty()) {
            String res = "==Messages==\n";
            for (Message message : messageVector) {
                res += message.toString() + "\n";
            }
            return res;
        }
        // 5. 未查询到信息
        return "none";
    }

    /**
     * 输出指令菜单
     *
     * @return
     * @throws RemoteException
     */
    @Override
    public String help() throws RemoteException {
        String tab = "\t";
        String lf = "\n";
        String info = "RMI MENU:" + lf;
        for (int i = 0; i < 6; i++) {
            info += tab + (i + 1) + ". " + INSTRUCTIONS[i]
                    + tab + " : " + INSTRUCTIONS_DES[i] + lf;
            info += tab + tab + "arguments: " + INSTRUCTIONS_ARGS[i] + lf;
        }
        return info;
    }

    /**
     * 展示所有信息信息
     *
     * @return
     */
    public String displayMessages() {
        String res = "";
        messages = getMessages();
        for (Message message : messages) {
            res += message.toString() + "\n";
        }
        return res;
    }

    /**
     * 展示所有用户信息
     *
     * @return
     */
    @Override
    public String showUsers() {
        String res = "";
        users = getUsers();
        for (User user : users) {
            res += user.toString() + "\n";
        }
        return res;
    }

    /**
     * 判断 username是否已经存在
     *
     * @param username
     * @return  true：用户名已存在
     *          false：用户名不存在
     */
    public boolean hasUsername(String username) {
        users = getUsers();
        for (User user : users) {
            if (username.equals(user.getUsername())) {
                return true;
            }
        }
        return false;
    }
}
